package com.xiaoge;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpMethod;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import java.util.List;

/**
 * TODO @EnableWebMvc 底层原理
 * 		1. spring会把DelegatingWebMvcConfiguration注入到ioc容器中, 在bean生命周期中, 有找到该方法
 *      @Autowired(required = false)
 * 		public void setConfigurers(List<WebMvcConfigurer> configurers) {
 * 		if (!CollectionUtils.isEmpty(configurers)) {
 * 			this.configurers.addWebMvcConfigurers(configurers);
 *        }
 *      }
 *      2. 它回去spring容器中找WebMvcConfigurer该类型的bean, 而我们AppConfig就是该类型的, 然后调用setConfigurers方法因为它加了@Autowired注解spring会自动调用
 *		3. 有因为该类是个配置类, 它又会去找父类上定义的@bean方法调用,把它添加到spring容器中, 这个WebMvcConfigurer接口中的方法, 会在这个DelegatingWebMvcConfiguration类的父类中定义的各种@bean方法, 被spring调用的时候加入进去(spring mvc的handlerMapping/Adapt方法)
 * @author <a href="mailto:1330137071@qq.com">Zhang Xiao</a>
 * @since
 */
@ComponentScan("com.xiaoge")
   // todo 注意这个注解@EnableWebMvc和这个接口必须是搭配使用的要不然也没用, @EnableWebMvc的DelegatingWebMvcConfiguration类它会从写RequestMappingHandlerMapping这个bean
public class AppConfig implements WebMvcConfigurer {

	/**
	 * todo 自定义RequestMappingHandlerAdapter, 设置setSupportedMethods(HttpMethod.POST.name()),
	 * 	表示所有RequestMapping标注的方法只能支持post请求
	 * 	看DispatcherServlet->doDispatch->handle->handleInternal->checkRequest里面就写了为什么这样写只支持POST请求
	 *
	 * @return
	 */
//	@Bean
//	public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
//		RequestMappingHandlerAdapter requestMappingHandlerAdapter = new RequestMappingHandlerAdapter();
//		requestMappingHandlerAdapter.setSupportedMethods(HttpMethod.POST.name());
//		return requestMappingHandlerAdapter;
//	}


	/**
	 * todo 添加返回值转换器，转json
	 * @param converters initially an empty list of converters
	 */
//	@Override
//	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//		converters.add(new MappingJackson2HttpMessageConverter());
//	}

	/**
	 * todo 解决No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer
	 * @param converters initially an empty list of converters
	 */
//	@Override
//	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//		ObjectMapper mapper = new ObjectMapper();
//		mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
//		MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(mapper);
//		converters.add(converter);
//	}

	/**
	 * todo 自己定义这个bean给它添加前缀后缀, 因为默认dispatcherServlet初始化的时候去DispatcherServlet.properties找到它构建出来的是个, 它的这两个属性默认为空字符串
	 * @return
	 */
	@Bean
	public InternalResourceViewResolver internalResourceViewResolver() {
		InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
		internalResourceViewResolver.setPrefix("/WEB-INF/");
		internalResourceViewResolver.setSuffix(".jsp");
		return internalResourceViewResolver;

		// todo http://localhost:8080/WEB-INF/index.jsp  注意最终访问的这个是跟dispatcherServlet没关系的, dispatcherServlet是拦截/app/开头的路径, 因为我们配置的事/app/*
	}
}
